package pure.engine.model 
{
	import flash.filters.BitmapFilter;
	import pure.engine.core.ns_despair;
	import pure.engine.world.Mirror;
	import pure.engine.world.World;
	import pure.engine.world.WorldBody;
	use namespace ns_despair;

	/**
	 * 模型
	 * [Author] - PURE
	 * 
	 * [Hint] - 模型无法控制它自身是否"可见"，可操控渲染器是否可见.
	 */
public class Model2D extends RendererCarrier 
{	
	
	
	//======================
	// Const
	//======================
	
	
	ns_despair static const r_yDirtyFlag:uint         =  0x01;  // y坐标变化
	
	ns_despair static const r_noMirrorFlag:uint       =  0x10;  // 未发生残像，没有在渲染区
	ns_despair static const r_addedToModifyFlag:uint  =  0x20;  // 已加入脏列表
	
	
	
	//======================
	// Property
	//======================
	
	
	/**
	 * 坐标x
	 */
	public function get x():Number
	{ 
		return m_x; 
	}
	
	public function set x(v:Number):void 
	{
		if (m_x != v)
		{
			if (!Boolean(m_flags & r_noMirrorFlag))
			{
				cachedOffsetX += v - m_x;
				this._setModelDirty(false);
			}
			m_x = v;
		}
	}
	
	
	/**
	 * 坐标y
	 */
	public function get y():Number
	{ 
		return m_y;
	}
	
	public function set y(v:Number):void 
	{
		if (m_y != v)
		{
			if (!Boolean(m_flags & r_noMirrorFlag))
			{
				cachedOffsetY += v - m_y;
				this._setModelDirty(Boolean(cachedOffsetY));
			}
			m_y = v;
		}
	}
	
	
	/**
	 * 透明度
	 */
	public function get alpha():Number
	{ 
		return m_alpha; 
	}
	
	public function set alpha(v:Number):void 
	{
		this.m_alpha = v;
		if (m_mirror)
		{
			m_mirror.alpha = v;
		}
	}	
	
	/**
	 * 世界
	 */
	public function get worldbody():WorldBody
	{
		return m_worldbody; 
	}
	
	
	
	
	/**
	 * 移动
	 * 
	 * [Param] - x  坐标x
	 * [Param] - y  坐标y
	 */
	public function move(x:Number, y:Number):void
	{
		if (!Boolean(m_flags & r_noMirrorFlag))
		{
			cachedOffsetX += x - m_y;
			cachedOffsetY += y - m_y;
			this._setModelDirty(Boolean(cachedOffsetY));
		}
		m_x = x;
		m_y = y;
	}
	
	
	public function scroll(offsetX:Number, offsetY:Number):void
	{
		if (!Boolean(m_flags & r_noMirrorFlag))
		{
			cachedOffsetX += offsetX;
			cachedOffsetY += offsetY;
			this._setModelDirty(Boolean(cachedOffsetY));
		}
		m_x += offsetX;
		m_y += offsetY;
	}
	
	
	/**
	 * 初期化
	 */
	public function initialize():void
	{
		m_flags = r_noMirrorFlag;
		m_id = ++cachedCount
		m_modelMap[m_id] = this;
	}
	
	
	/**
	 * 杀死
	 * 
	 * [Hint] - 针对单体
	 */
	public function kill():void
	{
		m_worldbody.removeModel(this, Boolean(m_flags & r_yDirtyFlag));
		if (!Boolean(m_flags & r_noMirrorFlag))
		{
			m_mirror.destroy();
		}
		destroy();
	}
	
	
	/**
	 * [Override]
	 * 
	 * 加入滤镜
	 * 
	 * [Param] - F  滤镜
	 */
	override public function addFilter(F:BitmapFilter):void
	{
		super.addFilter(F);
		if(m_mirror)
		{
			m_mirror.filters = m_filterList;
		}
	}
	
	
	/**
	 * [Override]
	 * 
	 * 清空滤镜
	 */
	override public function clearFilter():void
	{
		super.clearFilter();
		if (m_mirror)
		{
			m_mirror.filters = null;
		}
	}
	
	
	/**
	 * 加入世界
	 * 
	 * [Param] - b  [true]可渲染，[false]不可渲染
	 */
	ns_despair function addToWorld(b:Boolean):void
	{
		var l:int = m_numRenderer;
		
		while (--l > -1)
		{
			m_rendererList[l].addToWorld(b);
		}
		m_flags = b ? 0 : r_noMirrorFlag;
	}
	
	
	/**
	 * 设置渲染状态
	 * 
	 * [Param] - b  [true]不可渲染，[false]可渲染
	 */
	ns_despair function setRenderEnabled(disabled:Boolean):void
	{
		if (Boolean(m_flags & r_noMirrorFlag) != disabled)
		{
			m_flags = disabled ? r_noMirrorFlag : 0;
			
			var l:int = m_numRenderer;
			if (disabled)
			{
				m_mirror.destroy();
				m_mirror = null;
				while (--l > -1)
				{
					m_rendererList[l].disable();
				}
			}
			else
			{
				while (--l > -1)
				{
					m_rendererList[l].enable();
				}
			}
		}
	}
	
	
	/**
	 * 更改
	 * 
	 * [Hint] - 全局照亮更新残像时使用
	 */
	ns_despair function modify():void
	{
		m_mirror.update(cachedOffsetX, cachedOffsetY);
		m_flags = cachedOffsetX = cachedOffsetY = 0;
	}
	
	
	/**
	 * 绑定
	 * 
	 * [Hint] - 残像初次映射，无视渲染器状态
	 */
	ns_despair function createMirror():Mirror
	{
		var i:int;
		
		m_mirror = Mirror.getMirror();
		for (i = 0; i < m_numRenderer; i++)
		{
			m_mirror.addChild(m_rendererList[i].m_fragment);
		}
		
		m_mirror.x = this.m_x;
		m_mirror.y = this.m_y;
		m_mirror.m_id = this.m_id;
		m_mirror.alpha = this.m_alpha;
		
		if (m_filterList)
		{
			m_mirror.filters = m_filterList;
		}
		
		return m_mirror;
	}
	
	
	/**
	 * 毁灭
	 * 
	 * [Hint] - 不包含残像的销毁，通常使用于群体模型销毁
	 */
	override ns_despair function destroy():void
	{
		super.destroy();
		
		delete m_modelMap[this.m_id];
		cachedOffsetX = cachedOffsetY = 0;
		m_worldbody = null;
		m_mirror = null;
		m_alpha = 1;
	}
	
	
	
	
	/* ----------------------------------------------------------------------------------------------------------------
	 * ★★★★★★★★★★★★★★★★★★★★★  private  ★★★★★★★★★★★★★★★★★★★★★
	 * ----------------------------------------------------------------------------------------------------------------
	 */
	

	
	
	/**
	 * 设置脏模型
	 * 
	 * [Param] - yDirty  是否y坐标变化
	 */
	ns_despair function _setModelDirty(yDirty:Boolean):void
	{
		if(!Boolean(m_flags & r_addedToModifyFlag))
		{
			m_worldbody.addDirtyModel(this);
			m_flags |= r_addedToModifyFlag;
		}
		if (yDirty)
		{
			m_flags |= r_yDirtyFlag
		}
		else
		{
			m_flags &= ~r_yDirtyFlag;
		}
	}

	
	/**
	 * 获取模型
	 */
	ns_despair static function getModelByID(modelID:uint):Model2D
	{
		return m_modelMap[modelID];
	}
	
	
	
	
	//======================
	// Member
	//======================
	
	
	ns_despair static var cachedCount:int;  // 实体id计数
	
	ns_despair static var m_modelMap:Object = { };
	

	ns_despair var m_worldbody:WorldBody;
	
	ns_despair var m_mirror:Mirror;  // 残像
	
	ns_despair var m_grid:int;
	
	ns_despair var m_alpha:Number = 1
	
	ns_despair var cachedOffsetX:Number = 0;

	ns_despair var cachedOffsetY:Number = 0;
	
	public var m_id:int;  // 识别
	
	public var m_layerIndex:int;  // 图层

}

}